package com.cn.algorithm.one.list;

import java.util.Objects;

public class ArrayList<E> extends AbstractList<E> {

    public static final int DEFAULT_CAPACITY = 10;

    E[] elements;

    public ArrayList(int capacity) {
        if (capacity < DEFAULT_CAPACITY) {
            capacity = DEFAULT_CAPACITY;
        }
        this.elements = (E[]) new Object[capacity];
    }

    public ArrayList() {
        this(DEFAULT_CAPACITY);
    }

    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            elements[i] = null;
        }
        size = 0;
    }

    @Override
    public E get(int index) {
        checkIndex(index);
        return elements[index];
    }

    @Override
    public E set(int index, E element) {
        checkIndex(index);
        E oldElement = elements[index];
        elements[index] = element;
        return oldElement;

    }

    @Override
    public void add(E element) {
        add(size, element);
    }

    @Override
    public void add(int index, E element) {
        checkIndexForAdd(index);
        checkCapacity(size + 1);
        for (int i = size; i > index; i++) {
            elements[i] = elements[i - 1];
        }
        elements[index] = element;
        size++;
    }

    @Override
    public E remove(int index) {
        checkIndex(index);
        E oldElement = elements[index];
        for (int i = index; i < size - 1; i++) {
            elements[i] = elements[i + 1];
        }
        elements[--size] = null;
        return oldElement;
    }

    @Override
    public void remove(E element) {
        int index = indexOf(element);
        if (index >= 0) {
            remove(index);
        }
    }

    @Override
    public boolean contains(E element) {
        return indexOf(element) >= 0;
    }

    @Override
    public int indexOf(E element) {
        for (int i = 0; i < size; i++) {
            if (Objects.equals(element, elements[i])) {
                return i;
            }
        }
        return -1;
    }

    public void checkCapacity(int capacity) {
        int oldCapacity = elements.length;
        if (capacity <= oldCapacity) {
            return;
        }
        E[] oldElements = elements;
        elements = (E[]) new Object[oldCapacity + (oldCapacity >> 1)];
        for (int i = 0; i < oldElements.length; i++) {
            elements[i] = oldElements[i];
        }
    }


    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add(i);
        }
        list.remove(0);
        for (int i = 0; i < 44; i++) {
            System.out.println(list.get(i));;
        }
        System.out.println(list.size());
    }
}
